<template>
  <div>
    <!-- 表单占位布局 -->
    <div v-if="!formKeys" style="width: 90%; margin: auto">
      <div class="row_placeholder">
        <div class="cell_placeholder"></div>
        <div class="cell_placeholder"></div>
      </div>
      <div class="row_placeholder">
        <div class="cell_placeholder"></div>
        <div class="cell_placeholder"></div>
      </div>
    </div>
    <!-- 表单内容 -->
    <div
      :style="{
        width: type == 'grid' ? gridWidth : width,
        'margin-left': align == 'center' ? 'auto' : '',
        'margin-right': align == 'center' ? 'auto' : '',
        'float': align == 'right' ? 'right' : 'none',
      }"
      :class="{ grid: type == 'grid' }"
      v-else
    >
      <div v-if="type == 'grid'" class="header display_flex align_items_center">
        <slot name="header" />
      </div>
      <div v-for="r in rows" :key="r" :class="{row: isShowRow(r)}">
        <div
          v-for="c in handleRowMerged(r, cols).cols"
          :key="c"
          class="cell"
          :style="{
            width: isMerged(r, c, cols) ?
              `calc((100% - ${ handleCellSpace().num * (cols - 1) + handleCellSpace().unit }) / ${ cols } *
            ${ rowMergedNum(r, cols) } + ${ handleCellSpace().num * (rowMergedNum(r, cols) - 1) + handleCellSpace().unit })` :
              `calc((100% - ${ handleCellSpace().num * (cols - 1) + handleCellSpace().unit }) / ${ cols })`,
            'margin-left': type == 'grid' ? 0 : c != 1 ? cellSpace : 0,
            ...handleStyle(data[getFormKey(r, c)])
          }"
        >
          <template v-if="getFormKey(r, c)">
            <span
              v-if="data[getFormKey(r, c)].label"
              class="label_css"
              :class="{
                required: data[getFormKey(r, c)].required
              }"
              :style="{
                width: type == 'grid' ? gridLabelWidth : data[getFormKey(r, c)].labelWidth ? data[getFormKey(r, c)].labelWidth : labelWidth,
                'margin-left': type == 'grid' ? 0 : data[getFormKey(r, c)].labelWidth ? `calc(${ labelWidth } - ${ data[getFormKey(r, c)].labelWidth })` : '',
                'text-align': labelPosition
              }"
            >
              <template v-if="data[getFormKey(r, c)].tip">
                <Prompt
                  v-if="data[getFormKey(r, c)].tipOptions && data[getFormKey(r, c)].tipOptions.position == 'before'"
                  :isContent="data[getFormKey(r, c)].tipOptions && data[getFormKey(r, c)].tipOptions.isContent"
                  class="prompt"
                  style="margin-right: 5px"
                >
                  <template v-if="data[getFormKey(r, c)].tipOptions">
                    {{data[getFormKey(r, c)].tipOptions.title}}
                  </template>
                </Prompt>
              </template>
              <span>{{ data[getFormKey(r, c)].label }}</span>
            </span>
            <div
              class="form_item"
              :style="{
                width: data[getFormKey(r, c)].label ? `calc(100% - ${ type == 'grid' ? gridLabelWidth : labelWidth })` : '100%',
              }"
              v-tab="{
                index: getFormTabIndex(r, c),
                area: name,
                max: max,
                removeTab: readonly || data[getFormKey(r, c)].readonly || data[getFormKey(r, c)].removeTab ||
                  (data[getFormKey(r, c)].tabs && data[getFormKey(r, c)].tabs > 1) ? true : false
              }"
            >
              <slot
                v-if="data[getFormKey(r, c)].slot"
                :name="getFormKey(r, c)"
                :tab="{
                  index: getFormTabIndex(r, c),
                  area: name,
                  max: max,
                  removeTab: readonly || data[getFormKey(r, c)].readonly ||
                    (data[getFormKey(r, c)].tabs && data[getFormKey(r, c)].tabs > 1) ? true : false
                }"
              />
              <!-- 下拉框 -->
              <el-select
                v-else-if="data[getFormKey(r, c)].type == 'select'"
                v-model="data[getFormKey(r, c)].value"
                :placeholder="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.placeholder ||
                  '请选择' + data[getFormKey(r, c)].label.replace('：', '')"
                :clearable="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.clearable == true ? true : false"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
              >
                <el-option
                  v-for="(s, sIdx) in data[getFormKey(r, c)].options"
                  :key="sIdx"
                  :value="typeof s == 'object' ? s[data[getFormKey(r, c)].opValueKey || 'id'] : s"
                  :label="typeof s == 'object' ? s[data[getFormKey(r, c)].opLabelKey || 'name'] : s"
                  :disabled="typeof s == 'object' ? data[getFormKey(r, c)].opDisabledName || s.disabled : false"
                ></el-option>
              </el-select>
              <!-- 级联选择器 -->
              <el-cascader
                v-else-if="data[getFormKey(r, c)].type == 'cascader'"
                v-model="data[getFormKey(r, c)].value"
                :ref="getFormKey(r, c)"
                :options="data[getFormKey(r, c)].options"
                :props="{
                  checkStrictly: true,
                  emitPath: false,
                  ...data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.props,
                  value: data[getFormKey(r, c)].opValueKey || 'id',
                  label: data[getFormKey(r, c)].opLabelKey || 'name'
                }"
                :placeholder="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.placeholder ||
                  '请选择' + data[getFormKey(r, c)].label.replace('：', '')"
                :clearable="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.clearable == true ? true : false"
                @change="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.props &&
                  data[getFormKey(r, c)].attrs.props.multiple ? false : $refs[getFormKey(r, c)][0].dropDownVisible = false"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
              ></el-cascader>
              <!-- 日期选择器 -->
              <el-date-picker
                v-else-if="data[getFormKey(r, c)].type == 'date'"
                v-model="data[getFormKey(r, c)].value"
                :class="[data[getFormKey(r, c)].className, { readonly: readonly }]"
                :placeholder="data[getFormKey(r, c)].attrs ? data[getFormKey(r, c)].attrs.placeholder ?
                  data[getFormKey(r, c)].attrs.placeholder : data[getFormKey(r, c)].attrs.readonly ? '' :
                    '请选择' + data[getFormKey(r, c)].label.replace('：', '') : '请选择' + data[getFormKey(r, c)].label.replace('：', '')"
                :format="data[getFormKey(r, c)].attrs ? data[getFormKey(r, c)].attrs.format ?
                  data[getFormKey(r, c)].attrs.format : data[getFormKey(r, c)].attrs.type == 'datetime' ?
                    'yyyy-MM-dd HH:mm' : 'yyyy-MM-dd' : 'yyyy-MM-dd'"
                :value-format="data[getFormKey(r, c)].attrs ? data[getFormKey(r, c)].attrs.valueFormat ?
                  data[getFormKey(r, c)].attrs.valueFormat : data[getFormKey(r, c)].attrs.type == 'datetime' ?
                    'yyyy-MM-dd HH:mm' : 'yyyy-MM-dd' : 'yyyy-MM-dd'"
                :clearable="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.clearable == true ? true : false"
                :readonly="readonly ? true : data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.readonly ? data[getFormKey(r, c)].attrs.readonly : false"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
              ></el-date-picker>
              <!-- 时间选择器 -->
              <el-time-picker
                v-else-if="data[getFormKey(r, c)].type == 'time'"
                v-model="data[getFormKey(r, c)].value"
                :placeholder="data[getFormKey(r, c)].attrs ? data[getFormKey(r, c)].attrs.placeholder ?
                  data[getFormKey(r, c)].attrs.placeholder : data[getFormKey(r, c)].attrs.readonly ? '' :
                    '请选择' + data[getFormKey(r, c)].label.replace('：', '') : '请选择' + data[getFormKey(r, c)].label.replace('：', '')"
                :format="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.format || 'HH:mm'"
                :value-format="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.valueFormat || 'HH:mm'"
                :clearable="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.clearable == true ? true : false"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
              ></el-time-picker>
              <!-- 单选框组 -->
              <el-radio-group
                v-else-if="data[getFormKey(r, c)].type == 'radio'"
                v-model="data[getFormKey(r, c)].value"
                v-on="data[getFormKey(r, c)].events || {}"
              >
                <el-radio
                  v-for="rad in data[getFormKey(r, c)].options"
                  :key="rad[data[getFormKey(r, c)].opValueKey] || rad.id"
                  :label="rad[data[getFormKey(r, c)].opLabelKey] || rad.id"
                  :disabled="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.disabled"
                  :class="data[getFormKey(r, c)].className"
                >
                  {{ data[getFormKey(r, c)].opLabelKey ? rad[data[getFormKey(r, c)].opLabelKey] : rad.name }}
                </el-radio>
              </el-radio-group>
              <!-- 复选框组 -->
              <el-checkbox-group
                v-else-if="data[getFormKey(r, c)].type == 'checkbox'"
                v-model="data[getFormKey(r, c)].value"
                v-on="data[getFormKey(r, c)].events || {}"
              >
                <el-checkbox
                  v-for="ckb in data[getFormKey(r, c)].options"
                  :key="ckb[data[getFormKey(r, c)].opValueKey] || ckb.id"
                  :label="ckb[data[getFormKey(r, c)].opLabelKey] || ckb.id"
                  :disabled="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.disabled"
                >
                  {{ data[getFormKey(r, c)].opLabelKey ? ckb[data[getFormKey(r, c)].opLabelKey] : ckb.name }}
                </el-checkbox>
              </el-checkbox-group>
              <!-- 开关 -->
              <el-switch
                v-else-if="data[getFormKey(r, c)].type == 'switch'"
                v-model="data[getFormKey(r, c)].value"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
                class="stick"
              ></el-switch>
              <!-- 下拉自动选择 -->
              <el-autocomplete
                v-else-if="data[getFormKey(r, c)].type == 'autocomplete'"
                v-model="data[getFormKey(r, c)].value"
                :placeholder="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.placeholder ||
                  '请选择' + data[getFormKey(r, c)].label.replace('：', '')"
                :value-key="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.valueKey || 'name'"
                v-input="{belong: `data.${ getFormKey(r, c) }.value`, reg: data[getFormKey(r, c)].directives && data[getFormKey(r, c)].directives.input}"
                v-blur="{
                  belong: `data.${ getFormKey(r, c) }.value`,
                  reg: data[getFormKey(r, c)].directives && data[getFormKey(r, c)].directives.blur,
                  removeBlur: readonly
                }"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
              >
              </el-autocomplete>
              <!-- 输入框 -->
              <el-input
                v-else
                :ref="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.type != 'textarea' ? 'input' : ''"
                v-model="data[getFormKey(r, c)].value"
                :class="[data[getFormKey(r, c)].className, {
                  readonly: readonly || type == 'grid' && data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.readonly
                }]"
                :placeholder="readonly ? '' : data[getFormKey(r, c)].attrs ? data[getFormKey(r, c)].attrs.placeholder ?
                  data[getFormKey(r, c)].attrs.placeholder : data[getFormKey(r, c)].attrs.readonly ? '' :
                    '请输入' + data[getFormKey(r, c)].label.replace('：', '') : '请输入' + data[getFormKey(r, c)].label.replace('：', '')"
                :show-password="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.type == 'password' &&
                  data[getFormKey(r, c)].attrs.showPassword != undefined ? data[getFormKey(r, c)].attrs.showPassword : false"
                :resize="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.type == 'textarea' ? 'none' : ''"
                :autosize="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.autosize ? data[getFormKey(r, c)].attrs.autosize :
                  data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.rows ? null : {minRows: 3}"
                :readonly="readonly ? true : data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.readonly ? data[getFormKey(r, c)].attrs.readonly : false"
                v-input="{belong: `data.${ getFormKey(r, c) }.value`, reg: data[getFormKey(r, c)].directives && data[getFormKey(r, c)].directives.input}"
                v-blur="{
                  belong: `data.${ getFormKey(r, c) }.value`,
                  reg: data[getFormKey(r, c)].directives && data[getFormKey(r, c)].directives.blur,
                  removeBlur: readonly
                }"
                v-bind="data[getFormKey(r, c)].attrs || {}"
                v-on="data[getFormKey(r, c)].events || {}"
              >
                <template v-if="data[getFormKey(r, c)].attrs && data[getFormKey(r, c)].attrs.type != 'textarea'">
                  <span v-if="data[getFormKey(r, c)].attrs.prefix" slot="prefix" v-html="data[getFormKey(r, c)].attrs.prefix"></span>
                  <span v-if="data[getFormKey(r, c)].attrs.suffix" slot="suffix" v-html="data[getFormKey(r, c)].attrs.suffix"></span>
                </template>
              </el-input>
              <template v-if="data[getFormKey(r, c)].tip">
                <Prompt
                  v-if="!data[getFormKey(r, c)].tipOptions || (data[getFormKey(r, c)].tipOptions && !data[getFormKey(r, c)].tipOptions.position) || (data[getFormKey(r, c)].tipOptions && !data[getFormKey(r, c)].tipOptions.position == 'after')"
                  :isContent="data[getFormKey(r, c)].tipOptions && data[getFormKey(r, c)].tipOptions.isContent"
                  class="prompt stick"
                >
                  <template v-if="data[getFormKey(r, c)].tipOptions">
                    {{data[getFormKey(r, c)].tipOptions.title}}
                  </template>
                </Prompt>
              </template>
            </div>
          </template>
        </div>
      </div>

      <slot name="content" :length="formLength" />

      <div class="btns" :class="{ grid_btns: type == 'grid' }" ref="btns">
        <slot />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Form',
  props: {
    name: {
      type: String,
      default: ''
    },
    data: {
      type: Object,
      default: null
    },
    rows: {
      type: Number,
      default: 0
    },
    cols: {
      type: Number,
      default: 0
    },
    cellSpace: {
      type: String,
      default: '100px'
    },
    mergeRow: {
      type: Array,
      default: () => []
    },
    mergeTab: {
      type: Object,
      default: () => {
        return {
          max: 0,
          add: 0
        };
      }
    },
    type: {
      type: String,
      default: 'default'
    },
    // 样式
    width: {
      type: String,
      default: '94%'
    },
    gridWidth: {
      type: String,
      default: '100%'
    },
    align: {
      type: String,
      default: 'center'
    },
    labelPosition: {
      type: String,
      default: 'right'
    },
    labelWidth: {
      type: String,
      default: '90px'
    },
    gridLabelWidth: {
      type: String,
      default: '140px'
    },
    readonly: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    data: {
      handler(newVal) {
        // console.log(newVal);
        if (newVal) {
          this.formKeys = {};
          this.formTabIndexs = {};
          let l = 0, lastTab = null;
          const tabsArr = [], lastPosition = [0, 0];
          this.dataHandled = this.$deepCopy(newVal);
          Object.values(this.dataHandled).map(item => { // 遍历一遍，拿到 tabs
            if (item.tabs) {
              tabsArr.push({
                position: item.position,
                tabs: item.tabs
              });
            }
          });
          for (const k in this.dataHandled) {
            if (this.dataHandled[k].position) {
              const r = this.dataHandled[k].position[0], c = this.dataHandled[k].position[1],
                kName = this.recurseForSort(this.dataHandled, k, r, c);
              if (kName) {
                this.formKeys[kName] = k;
                this.formTabIndexs[kName] = (Number(kName.split('_')[0].replace('r', '')) - 1) * this.cols + Number(kName.split('_')[1].replace('c', ''));
              }
              if (r > lastPosition[0] || r == lastPosition[0] && c > lastPosition[1]) {
                lastPosition[0] = r;
                lastPosition[1] = c;
              }
              tabsArr.map(item => {
                if (r > item.position[0] || r == item.position[0] && c > item.position[1]) {
                  this.formTabIndexs[kName] += item.tabs - 1;
                }
              });
            }
          }
          // console.log(this.formKeys);
          // console.log(this.formTabIndexs);
          lastTab = tabsArr.find(item => JSON.stringify(item.position) == JSON.stringify(lastPosition));
          Object.values(this.formTabIndexs).map(num => {
            l = num > l ? num : l;
          });
          if (lastTab) {
            l += lastTab.tabs - 1;
          }

          this.formLength = l;

          if (this.mergeTab.max) {
            this.max = this.mergeTab.max;
          } else {
            this.max = l;
          }
          if (this.mergeTab.add) {
            for (const k in this.formTabIndexs) {
              this.formTabIndexs[k] += this.mergeTab.add;
            }
          }
        }
      },
      deep: true,
      immediate: true
    }
  },
  updated() {
    this.$nextTick(() => {
      if (this.$refs.input) {
        this.$refs.input.map(el => {
          if (el.$attrs.prefixWidth) {
            el.$el.querySelector('.el-input__inner').style.paddingLeft = el.$attrs.prefixWidth;
          }
          if (el.$attrs.suffixWidth) {
            el.$el.querySelector('.el-input__inner').style.paddingRight = el.$attrs.suffixWidth;
          }
        });
      }
    });
  },
  activated() {
    this.$store.commit('layout/initManuallyRefresh', async() => {
    });
  },
  data() {
    return {
      formKeys: null, // 存储对应表单元素的key值，存储格式为 r**_c**: key
      formTabIndexs: null, // 存储对应表单元素的tabIndex值，存储格式为 r**_c**: key
      max: 0, // 表单需要 tab 切换的长度
      formLength: 0, // 表单的长度
      dataHandled: null,
    };
  },
  methods: {
    handleCellSpace() { // 将 cellSpace 拆分为数字和单位
      const num = this.type == 'grid' ? 0 : this.cellSpace.match(/\d+\.?\d*/)[0], // 找到数字
        unit = this.type == 'grid' ? 'px' : this.cellSpace.replace(num, ''); // 找到单位
      return {
        num,
        unit
      };
    },
    handleRowMerged(r, cols) { // 处理行合并，哪一行哪一列向右合并多少个
      if (this.mergeRow.length) {
        const tag = this.mergeRow.find(item => item[0] == r); // 判断并找到需要合并的行
        if (tag && tag.length > 2) { // 0，1 为行、列，必须大于两位
          tag[2] = tag[2] <= cols - tag[1] ? tag[2] : cols - tag[1]; // 重置合并数
          if (tag[2] > 0) { // tag 第三位为合并数，小于等于 0 则不执行
            return {
              tag: tag,
              cols: cols - tag[2]
            };
          }
        }
      }
      return {
        tag: null,
        cols
      };
    },
    isMerged(r, c, cols) { // 是否为行合并单元格
      const { tag } = this.handleRowMerged(r, cols);
      return tag && r == tag[0] && c == tag[1];
    },
    rowMergedNum(r, cols) { // 行合并单元格总数（包含自己）
      const { tag } = this.handleRowMerged(r, cols);
      return tag && tag[2] + 1;
    },
    getFormKey(r, c) { // 获取对应表单元素的 key 值
      return this.formKeys[`r${ r }_c${ c }`];
    },
    getFormTabIndex(r, c) { // 获取对应表单元素的 tabIndex 值
      return this.formTabIndexs[`r${ r }_c${ c }`];
    },
    recurseForSort(valCopy, k, r, c) {
      if (r > 1 && !Object.values(valCopy).find(v => v.position && v.position[0] == r - 1 && v.position[1] == c)) {
        const prevMerge = this.mergeRow.find(m => m[0] == r - 1);
        if (!prevMerge || prevMerge && c > prevMerge[1] + prevMerge[2] + 1) {
          valCopy[k].position = [r - 1, c];
          return this.recurseForSort(valCopy, k, r - 1, c);
        }
      }
      if (r && c) {
        return 'r' + r + '_c' + c;
      }
    },
    isShowRow(r) {
      if (this.dataHandled) {
        for (const item of Object.values(this.dataHandled)) {
          if (item.position && item.position[0] == r) {
            return true;
          }
        }
      }
      return false;
    },
    handleStyle(obj) {
      return obj ? obj.style : {};
    }
  },
  components: {
    Prompt: () => import('@c/Prompt.vue')
  }
};
</script>

<style lang="scss" scoped>
.row {
  margin: 12px 0;
  .cell {
    display: inline-block;
    vertical-align: top;
    > * {
      min-height: 36px;
      vertical-align: top;
    }
    .label_css {
      display: inline-block;
      color: #333333;
      font-weight: 600;
      font-size: 14px;
      line-height: 20px;
      padding: 8px 10px 8px 0;
      text-align: right;
    }
    .form_item {
      display: inline-flex;
      align-items: center;
      flex-wrap: wrap;
      > *:not(.stick) {
        width: auto;
        flex: 1;
      }
      > .item_row {
        display: flex;
        flex: none;
        width: 100%;
        align-items: center;
        > *:not(.stick) {
          width: auto;
          flex: 1;
        }
        & + .item_row {
          margin-top: 8px;
        }
      }
    }
    .slot_item {
      flex: none !important;
      width: 100% !important;
      display: flex;
      align-items: center;
      & + .slot_item {
        margin-top: 12px;
      }
      .flex_item {
        width: auto;
        flex: 1;
      }
      .label_css {
        flex-shrink: 0;
        align-self: flex-start;
      }
    }
  }
}
// 网格表单样式
.grid {
  border-bottom: 1px solid #d9d9d9;
  .header {
    border: 1px solid #d9d9d9;
    border-bottom: 0;
    padding: 0 30px;
    max-height: 50px;
    margin-bottom: -1px;
    > :not(.right) {
      flex: 1;
      padding: 17px 0;
    }
  }
  .row {
    margin: 0;
    display: flex;
    .cell {
      display: inline-flex;
      border: 1px solid #d9d9d9;
      border-left: 0;
      border-bottom: 0;
      &:first-child {
        border-left: 1px solid #d9d9d9;
      }
      .label_css {
        width: 140px;
        background-color: #e9edf0;
        padding: 15px;
        align-self: stretch;
        border-right: 1px solid #d9d9d9;
      }
      .label_css + .form_item {
        display: flex;
        align-items: stretch;
        padding: 7px 15px;
        .el-radio-group, .el-checkbox-group, .el-switch {
          align-self: center;
        }
        .stick {
          align-self: center;
        }
      }
      .slot_item {
        align-self: stretch;
        > .label_css + * {
          margin: 0 15px;
        }
        & + .slot_item {
          margin-top: 0;
          border-top: 1px solid #d9d9d9;
          &.cell_item {
            border-top: 0;
          }
        }
      }
    }
  }
  .grid_btns {
    border: 1px solid #d9d9d9;
    border-bottom: 0;
    > * {
     margin-top: 15px;
     margin-bottom: 15px;
    }
  }
}
.btns {
  width: 100%;
  text-align: center;
  > * {
    min-width: 80px;
    display: inline-block;
    vertical-align: middle;
    margin: 20px 0;
    & + .el-button {
      margin-left: 25px;
    }
  }
}
.disable {
  &.el-input ::v-deep .el-input__inner {
    background: #f5f7fa;
  }
  &.el-textarea ::v-deep .el-textarea__inner {
    background: #f5f7fa;
  }
}
.readonly, .disable {
  &.el-input ::v-deep .el-input__inner {
    &:hover, &:focus {
      border-color: #DCDFE6 !important;
    }
  }
  &.el-textarea ::v-deep .el-textarea__inner {
    &:hover, &:focus {
      border-color: #DCDFE6 !important;
    }
  }
}
.grid .readonly {
  &.el-input ::v-deep .el-input__inner {
    border: 0;
  }
  &.el-textarea ::v-deep .el-textarea__inner {
    border: 0;
  }
}
.prompt {
  align-self: flex-start;
  line-height: 36px;
}
// 表单占位
.row_placeholder {
  display: flex;
  margin: 12px 0;
  justify-content: space-between;
  .cell_placeholder {
    width: calc(50% - 50px);
    height: 36px;
    border: 1px solid;
    border-radius: 4px;
    border-color:hsla(0, 0%, 95%, 0.1);
    background-color:hsla(0, 0%, 95%, 0.5);
  }
}
</style>
